﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FarseerGames.FarseerPhysics.Collisions;
using FarseerGames.FarseerPhysics.Mathematics;
using FreeGoo.GameEngine.Renderables.Particles.Keys;

namespace FreeGoo.GameEngine.Renderables.BodyHookOwners
{
    public class KeyedMotor : Motor
    {
        public KeyedMotor(Geom geom, Vector2 center, float hookRadius, int hookCount)
            : base(geom, center, hookRadius, hookCount)
        {
            CreateKeyhole();
            geom.OnCollision += Collide;
        }

        public enum Direction { Forward, Backward }

        public Keyhole Keyhole { get; set; }
        public float WantedAngularVelocityWhenRunning { get; set; }

        public bool Running
        {
            get
            {
                return Keyhole.IsLinked;
            }
        }

        public override void AddToEngine(Engine engine)
        {
            base.AddToEngine(engine);
            engine.Add(Keyhole);
        }

        public override void Delete()
        {
            base.Delete();
            Keyhole.Delete();
            Keyhole = null;
        }

        private bool Collide(Geom geometry1, Geom geometry2, ContactList contactList)
        {
            if (geometry1.Tag == null || !(geometry1.Tag is BodyRenderable) || geometry2.Tag == null || !(geometry2.Tag is BodyRenderable))
            {
                return true;
            }

            BodyRenderable thisRenderable1 = geometry1.Tag as BodyRenderable;
            BodyRenderable otherRenderable2 = geometry2.Tag as BodyRenderable;

            if (this == otherRenderable2)
            {
                otherRenderable2 = thisRenderable1;
            }

            if (otherRenderable2 is Key)
            {
                return false;
            }

            return true;
        }
        
        private void CreateKeyhole()
        {
            Keyhole = new Keyhole(this, Position, 8);
            Keyhole.OnKeyInserted += new Keyhole.KeyAction(Keyhole_OnKeyInserted);
            Keyhole.OnKeyRemoved += new Keyhole.KeyAction(Keyhole_OnKeyRemoved);
            Keyhole.OnKeyIsAllowed += new Keyhole.KeyQuery(Keyhole_OnKeyIsAllowed);
        }

        private void Keyhole_OnKeyRemoved(Key key)
        {
            TargetAngularVelocity = 0;
        }

        private bool Keyhole_OnKeyIsAllowed(Key key)
        {
            return key is KeyedMotorKey;
        }

        private void Keyhole_OnKeyInserted(Key key)
        {
            if ((key as KeyedMotorKey).Direction == Direction.Forward)
            {
                TargetAngularVelocity = WantedAngularVelocityWhenRunning;
            }
            else
            {
                TargetAngularVelocity = -WantedAngularVelocityWhenRunning;
            }
        }
    }
}
